/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。
 * 
 * 欢迎到知启蒙网站（https://www.zhiqim.com）购买正版软件，知启蒙还提供许多开源框架和软件。
 * 
 * 1、本软件产品所有源代码受《中华人民共和国著作权法》和其他有关法律、法规的保护，其所有知识产权归湖南知启蒙科技有限公司所有；
 * 2、禁止复制和修改。不得复制修改、翻译或改编本软件所有源代码，或者基于本软件产品创作衍生作品；
 * 3、禁止进行逆向工程。不得对本软件的源代码进行逆向工程、反编译或试图以其他方式发现软件的源代码；
 * 4、个别授权：如需进行商业性的销售、复制、分发，包括但不限于软件销售、预装、捆绑等，必须获得知启蒙的书面授权和许可；
 * 5、保留权利：本注释未明示授权的其他一切权利仍归知启蒙所有，任何人使用其他权利时必须获得知启蒙的书面同意。
*/
package net.redxyz.repost.service.task.repost;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import net.redxyz.repost.resource.model.AssRepostModel;
import net.redxyz.repost.service.Main;
import net.redxyz.repost.service.dao.UserDao;
import net.redxyz.top.dbo.sys.SysItemcat;
import net.redxyz.top.dbo.sys.SysParam;
import net.redxyz.top.dbo.user.User;
import net.redxyz.top.repost.dbo.AssRepostPlan;
import net.redxyz.top.repost.dbo.AssRepostPlanDetail;

import org.zhiqim.kernel.Global;
import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.logging.LogFactory;
import org.zhiqim.kernel.schedule.TaskLoad;
import org.zhiqim.kernel.util.DateTimes;
import org.zhiqim.orm.ORM;
import org.zhiqim.orm.ZTable;
import org.zhiqim.orm.dbo.Selector;

/**
 * 均匀上架调整计划
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 */
public class RepostPlanTask implements TaskLoad
{
    private static final Log log = LogFactory.getLog("timer.repost.log");
    private static final HashSet<String> idSet = new HashSet<String>();
    private String noCids = ","; // 不支持的类目，前面先加一个逗号

    public RepostPlanTask()
    {
        Global.add(RepostPlanTask.class, this);
    }

    public void remove(String id)
    {
        synchronized (idSet)
        {
            idSet.remove(id);
        }
    }

    private boolean add(String id)
    {
        synchronized (idSet)
        {
            return idSet.add(id);
        }
    }

    public void load()
    {
        try
        {
            // 从数据库读取数据
            SysParam param = ORM.get(ZTable.class).item(SysParam.class, "timer.param", "repostNoCids");
            noCids += (param == null) ? "" : param.getParamValue() + ",";

            // 239个卡
            Selector selector = new Selector();
            selector.addMaybe("parentCid", 99);

            List<SysItemcat> catList = ORM.get(ZTable.class).list(SysItemcat.class, selector);
            for (SysItemcat itemcat : catList)
            {
                noCids += itemcat.getCid() + ",";
            }

            log.info("加载点卡商品类目完成");
        }
        catch (Exception e)
        {
            log.error("加载商品类目失败", e);
        }
    }

    public void execute()
    {
        log.info("均衡上下架任务开始......");

        int week = DateTimes.getCurrentWeek7();
        String time = DateTimes.getTimeString().substring(0, 6) + "00";
        long time1 = System.currentTimeMillis();

        List<AssRepostPlanDetail> detailList = new ArrayList<AssRepostPlanDetail>();

            try
            {
                // 第一步,查出未执行的并且该星期值该时间点的列表
                Selector selector = new Selector();
                selector.addMaybe("operateStatus", 0);
                selector.addMaybe("planWeek", week);
                selector.addMaybe("planTime", time);
                selector.addReplace("d", "001");
                
                List<AssRepostPlanDetail> list1 = ORM.table().list(AssRepostPlanDetail.class, selector);
                
                //查询延迟调整宝贝
                Selector sel = new Selector();
                sel.addMaybe("itemStatus", 4);
                sel.addReplace("d", "001");
                List<AssRepostPlanDetail> list2 = ORM.table().list(AssRepostPlanDetail.class, sel);
                
                detailList.addAll(list1);
                detailList.addAll(list2);
            }
            catch (Exception e)
            {
                log.error("均衡上下架读取计划详情数据异常");
                return;
            }

        if (detailList.isEmpty())
        {
            log.info("均衡上下架结束[本分钟内没有要调整的宝贝]");
            return;
        }

        log.info("均衡上下架共有[" + detailList.size() + "]个宝贝需要处理");

        // 第二步,查找用户
        HashMap<String, User> userMap = new HashMap<String, User>();
        for (AssRepostPlanDetail detail : detailList)
        {
            String nick = detail.getNick();
            if (userMap.containsKey(nick))
                continue;

            try
            {
                User user = UserDao.getUser(nick);
                userMap.put(nick, user);
            }
            catch (Exception e)
            {
                log.error("均衡上架[" + nick + "]查询用户信息失败");
            }
        }

        // 第三步,对不能处理的进行清理
        for (Iterator<AssRepostPlanDetail> it = detailList.iterator(); it.hasNext();)
        {
            AssRepostPlanDetail detail = it.next();
            String nick = detail.getNick();
            if (!userMap.containsKey(nick))
            {// 查询用户信息失败,删除信息不处理
                it.remove();
                continue;
            }

            User user = userMap.get(nick);
            if (user == null || user.getUserStatus() != 0)
            {// 查询用户不存在或到期,删除用户均衡上架信息，这里暂不作清理处理，因为清理太慢，影响每分钟任务
                it.remove();

                    // 删除均衡上架计划日志
                    try
                    {
                        ORM.table().delete(AssRepostPlan.class, new Selector("nick", nick));
                    }
                    catch (Exception e)
                    {}
                    // 删除均衡上架计划详情
                    try
                    {
                        ORM.table().delete(AssRepostPlanDetail.class, new Selector("nick", nick).addReplace("d", "001"));
                    }
                    catch (Exception e)
                    {}
                    log.error("均衡上下架用户[" + nick + "]不存在或已到期");
            }

            long cid = detail.getCid();
            if (noCids.indexOf("," + cid + ",") != -1)
            {
                it.remove();
                log.error("均衡上下架用户[" + nick + "]类目不支持");
                continue;// 充值,点卡,酒店等不支持的类目
            }
        }

        // 第四步,循环下架再上架操作
        for (AssRepostPlanDetail detail : detailList)
        {
            String nick = detail.getNick();
            User user = userMap.get(nick);

            AssRepostModel dto = new AssRepostModel();
            dto.setNick(nick);
            dto.setSessionId(user.getSessionId());
            dto.setEmail(user.getEmail());

            String planId = detail.getPlanId();
            long numIid = detail.getNumIid();
            dto.setPlanId(planId);
            dto.setNumIid(numIid);
            dto.setDelay(detail.getItemStatus() == 4);

            dto.setItemTitle(detail.getItemTitle());
            dto.setItemPicUrl(detail.getItemPicUrl());
            dto.setItemNum(detail.getItemNum());

            String id = planId + "_" + numIid;

            if (add(id))
                Global.getService(Main.class).postRequest(dto);
        }

        while (!idSet.isEmpty())
        {
            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
                return;
            }

            log.info("均衡上下架任务处理，还剩[" + idSet.size() + "]条消息处理中，等待下1秒检查");
        }

        long time2 = System.currentTimeMillis();
        long subTime = (time2 - time1) / 1000;
        log.info("均衡上下架任务完成，共处理[" + subTime + "]秒");
    }

}
